<!--
Copyright 2003 Cordys R&D B.V. 

This file is part of the Cordys SAP Connector. 

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!--
 Project  : Cordys BAC
 File Name : sapusermapping.htm
 Description : This page is used to map cordys users to SAP users.
 author : Vijaya Gopal
-->
<html xmlns:eibus="xmlns:eibus" onselect="setOrganization()">
	<head>
		<title></title>
		<script src="/cordys/wcp/application.js"></script>
		<style>
			label {	 font-size:11; font-family:verdana; font-weight:normal; }
			input {	 font-size:11; font-family:verdana; font-weight:normal;}
			select {font-size:11; font-family:verdana; }
			button { font-size:11; font-family:verdana; width:95px}
			div {font-size:11; font-family:verdana; }
		</style>
	</head>	
	<script language="JScript">
		var userOrganizationDN, systemDN;//stores the DN of the current organization and system
		var userOrgName; //Name of the user organization.
		var orgUser;//stores all the organizational users name
		var sapNodes_org;//stores all the sap nodes names under organization
		var sapNodes_sys;//stores all the sap nodes names under system
		var Flag_SOAPFault;//this Flag_SOAPFault is changed when soapfault occurs.
		var rowCount = 0;
		/* It gets the application definition and the current organization and sets the title for the
		page and calls functions to get all the other required informations.*/
		function setOrganization()
		{
			orgUser = new Array();
			sapNodes_org = new Array();
			sapNodes_sys = new Array();
			Flag_SOAPFault = true;
			var applicationDef = application.event.applicationDefinition;
			window.application.container.setTitle(applicationDef.selectSingleNode("description").text,"BAC for SAP R/3");
			userOrganizationDN = application.organization;
			userOrgName = userOrganizationDN.split(",")[0].substring(2);
			removeOptions(txtOrg,1);
			txtOrg.options[1] = new Option(userOrgName,userOrganizationDN);
			if (userOrgName!="system")
			{
				systemDN = "o=system" + "," + userOrganizationDN.split(",")[1] + "," + userOrganizationDN.split(",")[2];
				txtOrg.options[2] = new Option("system",systemDN);
			}
			getAllSapNodes();
			getOrgUsers();
		}
		//This gets all the organizational users and stores them in an array.
		function getOrgUsers()
		{
			removeOptions(selCUser,1);
			var clone_getAllOrganizationalUsers = getAllOrganizationalUsers.XMLDocument.cloneNode(true);
			clone_getAllOrganizationalUsers.selectSingleNode("SOAP:Envelope/SOAP:Body/GetOrganizationalUsers/dn").text = userOrganizationDN;
			bdiCreateProfile.request = clone_getAllOrganizationalUsers;
			bdiCreateProfile.clear();
			bdiCreateProfile.reset();
			if(bdiCreateProfile.data.selectSingleNode("data/GetOrganizationalUsersResponse/tuple"))
			{
				var orgUsers = bdiCreateProfile.data ;
				var tupleNodes = orgUsers.getElementsByTagName("tuple");
				for(k = 0;k<tupleNodes.length;k++)
				{
					orgUser[k] = tupleNodes[k].selectSingleNode("old/entry").getAttribute("dn");
					selCUser.options[k+1] = new Option(orgUser[k].split(",")[0].substring(3),orgUser[k]);
				}
				getMappedUsersDetails(orgUser);
			}
			return;
		}
		//This gets all the Nodes attached sap connectors and stores them in an array.
		function getAllSapNodes()
		{
			getSOAPNodesInOrganization(userOrganizationDN, sapNodes_org);
			if (userOrgName!="system")
				getSOAPNodesInOrganization(systemDN, sapNodes_sys);
		}
		//To list the SAP nodes in the combo box
		function listSAPSoapNodes()
		{
			removeOptions(txtSN,1);
			if(txtOrg.value==userOrganizationDN)
			{
				for(i=0;i<sapNodes_org.length;i++)
				{
					txtSN.options[i+1] = new Option(sapNodes_org[i].split(",")[0].substring(3),sapNodes_org[i]);
				}
			}
			else
			{
				for(i=0;i<sapNodes_sys.length;i++)
				{
					txtSN.options[i+1]= new Option(sapNodes_sys[i].split(",")[0].substring(3),sapNodes_sys[i]);
				}
			}
		}
		//This is used for the validation of the page.
		function fnValidate()
		{
			if(txtOrg.value == 0)
			{
				alert("Select an Organization.");
				txtOrg.focus();
				return false;
			}
			else if(txtSN.value == 0)
			{
				alert("Select a SAP Service Group.");
				txtSN.focus();
				return false;
			}
			else if(selCUser.value == 0)
			{
				alert("Select the Cordys User to be mapped.");
				selCUser.focus();
				return false;
			}
			else if(!validText(txtSUser.value))
			{
				alert("Please enter the SAP User to which the mapping should be done.");
				txtSUser.select();
				return false;
			}
			else if(!validText(txtSPassword.value))
			{
				alert("Please enter the user password.");
				txtSPassword.select();
				return false;
			}
			return true;
		}
		// To validate the value entered in an input box
		function validText(givenText)
		{
			if (givenText == "" || !givenText.match(/\S/))
				return false;
			return true;
		}
		//This saves a new mapping in the LDAP.
		function saveMapping()
		{
			Flag_SOAPFault=true;
			if(fnValidate())
			{
				soapNodeDN = txtSN.value;
				soapNodeCN = soapNodeDN.split(",")[0];
				userDN = selCUser.value;
				var clone_requestUpdateProfile = requestUpdateProfile.XMLDocument.cloneNode(true);
				clone_requestUpdateProfile.selectSingleNode("SOAP:Envelope/SOAP:Body/Update/tuple/new/entry").setAttribute("dn",  soapNodeCN + "," + userDN)    ;
		        clone_requestUpdateProfile.selectSingleNode("SOAP:Envelope/SOAP:Body/Update/tuple/new/entry/cn/string").text  = soapNodeCN.substring(3);
		        clone_requestUpdateProfile.selectSingleNode("SOAP:Envelope/SOAP:Body/Update/tuple/new/entry/service/string").text  = soapNodeDN;
		       	clone_requestUpdateProfile.selectSingleNode("SOAP:Envelope/SOAP:Body/Update/tuple/new/entry/busmappedusername/string").text =  txtSUser.value;
				clone_requestUpdateProfile.selectSingleNode("SOAP:Envelope/SOAP:Body/Update/tuple/new/entry/busmappeduserpassword/string").text =  txtSPassword.encode(txtSPassword.value);
				bdiCreateProfile.clear();
		        bdiCreateProfile.request = clone_requestUpdateProfile;
		        bdiCreateProfile.reset();
				if(Flag_SOAPFault)
					getMappedUsersDetails(orgUser);
			}
		}
		//This is to set the Flag_SOAPFault everytime a soap fault occurs.
		function setFaultFlag()
		{
			Flag_SOAPFault = false;
		}
		// To initialize a row with nothing selected and empty text boxes
		function initializeRow()
		{
			txtOrg.value=0;
			selCUser.selectedIndex = 0;
			txtSN.selectedIndex = 0;
			txtSUser.value = "";
			txtSPassword.value = "";
		}
		/*Function Name : getMappedUsersDetails
			parameters:
				* DNUsers - Array of the organizational users
			Scope : This gets all the organizational users and stores them in an array.*/
		function getMappedUsersDetails(DNUsers)
		{
			if(tMappingDetails.rows.length>=2)
			{
				initializeRow();
				while(2<tMappingDetails.rows.length)
					tMappingDetails.deleteRow(tMappingDetails.rows.length-2);
			}
			var reqForMappings = SOAPReqXML.XMLDocument.cloneNode(true);
			var clone_getAllSAPMappings;
			for( userCount = 0;userCount < DNUsers.length; userCount++ )
			{
				clone_getAllSAPMappings = getAllSAPMappings.cloneNode(true);
				clone_getAllSAPMappings.selectSingleNode("GetChildren/dn").text = DNUsers[userCount];
				reqForMappings.selectSingleNode("SOAP:Envelope/SOAP:Body").appendChild(clone_getAllSAPMappings.firstChild);
			}
			bdiCreateProfile.clear();
			bdiCreateProfile.request = reqForMappings;
			bdiCreateProfile.reset();
			var ConfigurationXML = new ActiveXObject("Microsoft.XMLDOM");
			if(bdiCreateProfile.data.selectSingleNode("data/GetChildrenResponse/tuple"))
			{
				var entryNodes = bdiCreateProfile.data.getElementsByTagName("entry");
				for(j = 0;j<entryNodes.length;j++)
				{
					if(entryNodes[j].selectNodes(".//objectclass/string")[1].text=="bususerprofile")//to check only mapped nodes under one user.
					{
						cordysUser = entryNodes[j].getAttribute("dn").split(",")[1].substring(3);
						snName = entryNodes[j].selectSingleNode(".//cn/string").text
						orgName = entryNodes[j].selectSingleNode(".//service/string").text.split(",")[2].substring(2);
						if(orgName == userOrgName)
						{
							var sapNodes = sapNodes_org;
						}
						else if(orgName=="system")
						{
							sapNodes = sapNodes_sys;
						}
						for(z = 0;z<sapNodes.length;z++)
						{
							if(snName == sapNodes[z].split(",")[0].substring(3))
							{
								sapUserID = entryNodes[j].selectSingleNode(".//busmappedusername/string").text;
								dummyPass.value = entryNodes[j].selectSingleNode(".//busmappeduserpassword/string").text
								showDetailsInRow(cordysUser,sapUserID,dummyPass.decode(dummyPass.value),snName,orgName);
								break;
							}
						}
					}
				}
			}
			tMappingDetails.redraw();
		}
		/*Function Name : showDetailsInRow
			parameters:
				* cUser - Cordys User name
				* sUser - SAP userid
				* sn - SAP soap node
			Scope : This shows the mapped user details in a row.*/
		function showDetailsInRow(cUser,sUser,sPassword,sn,org)
		{
			rowCount = tMappingDetails.rows.length-1;
			newRow = tMappingDetails.insertRow(rowCount);
			nCell = newRow.insertCell();
			nCell.width = "2%";
			nCell.innerHTML = "<input type='checkbox' id='ch" + rowCount + "'/>"
			newCell = newRow.insertCell();
			newCell.innerHTML = "<label id='txtOrg" +rowCount+ "'   width='100%'>" +  org + "</label>"
			newCell1 = newRow.insertCell();
			newCell1.innerHTML = "<label id='txtSN" +rowCount+ "' >" + sn + "</label>"
			newCell2 = newRow.insertCell();
			newCell2.innerHTML = "<label id='txtCUser" +rowCount+ "'>" +  cUser + "</label>"
			newCell3 = newRow.insertCell();
			newCell3.innerHTML = "<label id='txtSUser" +rowCount+ "'  >" + sUser + "</label>"
			newCell4 = newRow.insertCell();
			//newCell4.innerHTML = "<input class='input' type='password' id='txtSPassword" +rowCount+ "' value='" + sPassword + "' disabled/ >"
			var dPassword="";
			for(var i=0;i<sPassword.length;i++)
			{
				dPassword=dPassword+"*";// To show asteriks in place of password
			}
			newCell4.innerHTML = "<label id='txtPassword" + rowCount+ " '>" + dPassword+ "</label>";
		}
		//This function is used to delete the selected mappings.
		function deleteMapping()
		{
			var checks = document.getElementsByTagName("input");
			var count = 0;
			var confirmed = false;
			for(i = 0;i<checks.length;i++)
			{
				if(checks[i].type=="checkbox" && checks[i].checked==true)
				{
					count++;
					if(!confirmed)
					{
						if(confirm("Are you sure you want to delete the selected User Mapping(s)?"))
						{
							confirmed = true;
							rowI = checks[i].id.substring(2);
							Flag = true;
							if(deleteLDAPEntry(rowI))
							{
								tMappingDetails.deleteRow(getToRow(checks[i],true) + 1);
								i=i-1;
							}
						}
						else
							return false;
					}
					else
					{
						rowI = checks[i].id.substring(2);
						Flag = true;
						if(deleteLDAPEntry(rowI))
						{
							tMappingDetails.deleteRow(getToRow(checks[i],true) + 1);
							i=i-1;
						}
					}
				}
			}
			if(count == 0)
				alert("Check at least one User Mapping to delete.");
			tMappingDetails.redraw();
			initializeRow();
		}
		//This function gets to row, by nagivating to the parent node
		function getToRow(object, indexed)
		{
			if (object && object.tagName.toLowerCase() == "tr")
			{
				if (indexed == true)
				{
					var rows = tMappingDetails.tBodies[0].rows;
					for (var i = 0; i < rows.length; i++)
					{
						if (object == rows[i]) return i;
					}
				}
				else return object;
			}
			else if (object) return getToRow(object.parentNode, indexed);
		}

		//This will delete the usermapping from the LDAP.
		function deleteLDAPEntry(rowI)
		{
			if (document.getElementById("txtOrg" + rowI).innerText == userOrgName )
				soapNodeDN = "cn=" + document.getElementById("txtSN" + rowI).innerText + ",cn=soap nodes," + userOrganizationDN;
			else
				soapNodeDN = "cn=" + document.getElementById("txtSN" + rowI).innerText + ",cn=soap nodes," + systemDN;
			soapNodeCN  =  soapNodeDN.split(",")[0];
			userDN = "cn=" + document.getElementById("txtCUser" + rowI).innerText + ",cn=organizational users," + userOrganizationDN;
			var clone_requestUpdateProfile = requestUpdateProfile.XMLDocument.cloneNode(true);
			var tupleNode = clone_requestUpdateProfile.selectSingleNode("SOAP:Envelope/SOAP:Body/Update/tuple");
			var entryNode = tupleNode.selectSingleNode("new/entry");
			var clone_entryNode = entryNode.cloneNode(true);
			tupleNode.removeChild(tupleNode.firstChild);
			var oldNode = tupleNode.ownerDocument.createElement("old");
			oldNode.appendChild(clone_entryNode);
			tupleNode.appendChild(oldNode);
			clone_requestUpdateProfile.selectSingleNode("SOAP:Envelope/SOAP:Body/Update/tuple/old/entry").setAttribute("dn",  soapNodeCN + "," + userDN);
			clone_requestUpdateProfile.selectSingleNode("SOAP:Envelope/SOAP:Body/Update/tuple/old/entry/cn/string").text  = soapNodeCN.substring(3);
			clone_requestUpdateProfile.selectSingleNode("SOAP:Envelope/SOAP:Body/Update/tuple/old/entry/service/string").text  = soapNodeDN;
			clone_requestUpdateProfile.selectSingleNode("SOAP:Envelope/SOAP:Body/Update/tuple/old/entry/busmappedusername/string").text = document.getElementById("txtSUser" + rowI).value;
			bdiCreateProfile.request = clone_requestUpdateProfile;
			bdiCreateProfile.clear();
			bdiCreateProfile.reset();
			return true;
		}
		//This function removes all the options from the select box.*/
		function removeOptions(idCombo,optlength)
		{
			while(optlength < idCombo.options.length)
				idCombo.remove(optlength);
		}
		// This function gets the SAP soap nodes in the given organization and stores them in the given array.
		function getSOAPNodesInOrganization(organization, soapNodeArray)
		{
			var clone_requestGetSOAPProcessors = requestGetSOAPProcessors.XMLDocument.cloneNode(true);
			clone_requestGetSOAPProcessors.selectSingleNode("SOAP:Envelope/SOAP:Body/GetSoapProcessors/dn").text = organization;
			bdiCreateProfile.request = clone_requestGetSOAPProcessors ;
			bdiCreateProfile.clear();
			bdiCreateProfile.reset();
			if(bdiCreateProfile.data.selectSingleNode("data/GetSoapProcessorsResponse/tuple/old/entry"))
			{
				var ConfigurationXML = new ActiveXObject("Microsoft.XMLDOM");
				var SoapProcessorDetails = bdiCreateProfile.data;
				var tupleNodes = SoapProcessorDetails.getElementsByTagName("entry");
		    	var chNodes, arrayFlag_SOAPFault, confNodes, confTags, confDet ;
				var count = 0;
				for(j = 0;j<tupleNodes.length;j++)
				{
					arrayFlag_SOAPFault = false;
					if(tupleNodes[j].selectSingleNode(".//bussoapprocessorconfiguration"))
					{
						confNodes = tupleNodes[j].selectSingleNode(".//bussoapprocessorconfiguration").firstChild;
						confDet = confNodes.text;
						ConfigurationXML.loadXML(confDet);
						if(ConfigurationXML.selectSingleNode(".//configuration"))
						{
							confTags = ConfigurationXML.selectNodes("configurations/configuration");
							for(var confTag = confTags.nextNode;confTag;confTag = confTags.nextNode)
							{
								var impl = confTag.getAttribute("implementation");
								if(impl == null) continue;
								if(impl.substring(impl.lastIndexOf(".")+1,impl.length)=="SAPMapper")
								{
									dnValue = tupleNodes[j].getAttribute("dn")
									dnSoapNode = dnValue.substring(dnValue.indexOf(",")+1,dnValue.length)
									if(sapNodes_org.length>0)
									{
										for(intI = 0; intI< sapNodes_org.length ; intI++)
										{
											if(dnSoapNode == sapNodes_org[intI])
											{
												arrayFlag_SOAPFault = true;
												break;
											}
										}
									}
									if(!arrayFlag_SOAPFault)
									{
										soapNodeArray[count] = dnSoapNode;
										count = count+1;
									}
								}
							}
						}
					}
				}
			}
		}
	</script>

<eibus:dataisland id="bdiCreateProfile" automatic="false" async="false" onsoapfault="setFaultFlag()" />
<xml id="SOAPReqXML">
	<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
	    <SOAP:Body/>
	</SOAP:Envelope>
</xml>
<xml id="getAllSAPMappings">
	<GetChildren xmlns="http://schemas.cordys.com/1.0/ldap">
	    <dn></dn>
    </GetChildren>
</xml>
<xml id="getAllOrganizationalUsers">
	<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
	    <SOAP:Body>
	        <GetOrganizationalUsers xmlns="http://schemas.cordys.com/1.0/ldap">
	            <dn></dn>
	        </GetOrganizationalUsers>
	    </SOAP:Body>
	</SOAP:Envelope>
</xml>
<xml id="requestGetSOAPProcessors">
	<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
	    <SOAP:Body>
	        <GetSoapProcessors xmlns="http://schemas.cordys.com/1.0/ldap">
	            <dn></dn>
	        </GetSoapProcessors>
	    </SOAP:Body>
	</SOAP:Envelope>
</xml>
<xml id="requestUpdateProfile">
    <SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
        <SOAP:Body>
            <Update xmlns="http://schemas.cordys.com/1.0/ldap">
               <tuple>
                   <new>
                      <entry>
                         <objectclass>
                           <string>top</string>
                           <string>bususerprofile</string>
                         </objectclass>
                         <cn><string></string></cn>
                         <profile><string/></profile>
                         <description><string/></description>
                         <service><string/></service>
                         <busmappedusername><string/></busmappedusername>
                         <busmappeduserpassword><string/></busmappeduserpassword>
                      </entry>
                    </new>
                </tuple>
             </Update>
        </SOAP:Body>
    </SOAP:Envelope>
</xml>
<xml id="requestDeleteProfile">
    <SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
        <SOAP:Body>
            <Update xmlns="http://schemas.cordys.com/1.0/ldap">
               <tuple>
                   <old>
                      <entry dn>
                         <objectclass>
                           <string>top</string>
                           <string>bususerprofile</string>
                         </objectclass>
                         <cn><string></string></cn>
                         <profile><string/></profile>
                         <service><string/></service>
                         <busmappedusername><string/></busmappedusername>
                         <busmappeduserpassword><string/></busmappeduserpassword>
                      </entry>
                    </old>
                </tuple>
             </Update>
        </SOAP:Body>
    </SOAP:Envelope>
</xml>

<body rightmargin="0" leftmargin="0" topmargin="20" bottommargin="0" scroll="no">
	<eibus:toolbar id="toolbar" class="lightmedium" style="width:100%">
		 <span class="coolButton" id="saveButton" onclick="saveMapping()" title="Save">
		     <img align="absmiddle" src="/cordys/wcp/images/save.gif" />
		 </span>
		 <span class="coolButton" id="deleteButton" onclick="deleteMapping()" title="Delete">
		     <img align="absmiddle" src="/cordys/wcp/images/delete.gif" />
		 </span>
	</eibus:toolbar>
	<br/>
	<input type"password" id="dummyPass" style="display:none" style="behavior:url('/cordys/wcp/admin/behavior/base64Encoder.htc')" />
	<table width="100%" height="90%" align="center" scroll="auto">
		<tr>
			<td align="center">
				<div style="width:100%; overflow:auto; height:95%">
					<table id="tMappingDetails" border="1" width="100%" class="grid medium" bordercolor="darkgray" align="center" displayContextMenu="false" movableColumns="false" sortable="true" saveState="false" shadeClasses = "mainbody lightmedium">
						<thead>
							<tr>
								<td width="5%" align="center">&nbsp;</td>
								<td width="22%" align="center">Organization</td>
								<td width="18%" align="center">SAP Service Group</td>
								<td width="20%" align="center">Cordys User</td>
								<td width="17%" align="center">SAP User</td>
								<td width="18%" align="center">User Password</td>
							</tr>
						</thead>
						<tbody>
							<tr class="mainbody">
								<td width="5%">
									<input type="checkbox" id="Newch" disabled />
								</td>
								<td>
									<select id="txtOrg" class="input" style="width:98%" onchange="listSAPSoapNodes()">
										<option value="0">-Select Organization-</option>
									</select>
								</td>
								<td>
									<select id="txtSN" class="input" style="width:98%">
										<option value="0">-Select SAP Service Group-</option>
									</select>
								</td>
								<td>
									<select id="selCUser" class="input" style="width:98%">
										<option value="0">-Select Cordys User-</option>
									</select>
								</td>
								<td>
									<input type="text" id="txtSUser" class="input" style="width:100%" />
								</td>
								<td>
									<input type="password" id="txtSPassword" class="input" style=" behavior:url('/cordys/wcp/admin/behavior/base64Encoder.htc');width:100%" />
								</td>
							</tr>
						</tbody>
					</table>
				</div>
			</td>
		</tr>
	</table>
</body>
</html>
